import { isEditableArea, toCells, isSameType,getNewValue } from ".";
import CellType from "../../../excel/celltypes";

export default {
    canUndo: true,
    execute: (context, options, isUndo) => {
        context.suspendPaint();
        try {
            const { store,sheet, sourceSheet, cellRange, oldValue, oldText, callback, sourceRange, value, oldTableValue } = options;
            const targetCells = toCells({ ...cellRange, sheet });
            if (isUndo) {
                targetCells.forEach((cell, index) => {
                    if(index===0) {
                        const table=sheet.tables.find(cell.row, cell.col);
                        if(table){
                            const bindingPath = table.bindingPath();
                            store.dataSourceInstance.setValue(bindingPath, oldTableValue);
                            table.bindingPath(bindingPath);
                            store.calcAll(true, sheet.name());
                        } 
                    }
                    const cellObj = sheet.getCell(cell.row, cell.col);
                    cellObj.text(oldText[index]);
                    cellObj.value(oldValue[index]);
                });
            } else {
                options.oldValue = targetCells.map(cell => cell.value);
                options.oldText = targetCells.map(cell => cell.text);
                if (sourceSheet && sourceRange) {
                    const sourceCells = toCells({ ...sourceRange, sheet: sourceSheet });
                    let getSourceCell;
                    if (sourceCells.length === 1) {
                        getSourceCell = () => {
                            return sourceCells[0]
                        }
                    } else {
                        getSourceCell = (index) => {
                            return sourceCells[index];
                        }
                    }
                    let table;
                    let isAddRow = 1;
                    targetCells.forEach((cell, index) => {
                        if(index===0){
                            table = sheet.tables.find(cell.row, cell.col);
                            if(table) options.oldTableValue = store.dataSourceInstance.getValue(table.bindingPath());
                        }else{
                            if(table&&table.dataRange){
                                const {row,rowCount,col,colCount} = table.dataRange();
                                const bindingPath = table.bindingPath();
                                const rowControl = store.rowControl;
                                const sheetName = sheet.name();
                                (rowControl[sheetName]||[]).forEach(item => {
                                    if(bindingPath == item.bindingPath){
                                        isAddRow = item.isAddRow;
                                        return;
                                    }
                                });
                                if(1==isAddRow){
                                    if(cell.row>row+rowCount-1){
                                        const tableValue = store.dataSourceInstance.getValue(bindingPath);
                                        const newValue = getNewValue(tableValue,cell.row-row-1,[],1);
                                        store.dataSourceInstance.setValue(bindingPath, newValue);
                                        table.bindingPath(bindingPath);
                                        const rowHeight = sheet.getRowHeight(row+rowCount-1,GC.Spread.Sheets.SheetArea.viewport);
                                        sheet.setRowHeight(cell.row, rowHeight, GC.Spread.Sheets.SheetArea.viewport);
                                        for(var c=0;c<colCount;c++){
                                            const cstyle = sheet.getStyle(row+rowCount-1,cell.col+c,GC.Spread.Sheets.SheetArea.viewport, true);
                                            if(cstyle) {
                                                cstyle.cellType = null;
                                                sheet.setStyle(cell.row,cell.col+c,cstyle,GC.Spread.Sheets.SheetArea.viewport);
                                            }
                                        }
                                        store.calcAll(true, sheet.name());
                                    }
                                }
                            }
                        }
                        if (isEditableArea(sheet.getCell(cell.row,cell.col))) {
                            const sourceCell = getSourceCell(index);
                            const cellObj = sheet.getCell(cell.row,cell.col)
                            const sourceCellObj = sheet.getCell(sourceCell.row,sourceCell.col)
                            if (sourceCellObj && isSameType(cellObj, sourceCellObj) && cellObj.cellType() && cellObj.cellType().viewAttr != '1') {
                                cellObj.text(sourceCell.text);
                                cellObj.cellType().doUpdateValue(cellObj, sourceCell.value);
                            }
                        }
                    });
                } else {
                    if (value) {
                        const valueTr = value.split('\r\n');
                        const values = [];
                        valueTr.forEach(tr => {
                            tr.split('	').forEach(td => {
                                values.push(td);
                            })
                        })
                        let getValue;
                        if (values.length === 1) {
                            getValue = () => {
                                return values[0]
                            }
                        } else {
                            getValue = (index) => {
                                return values[index];
                            }
                        }
                        const WeaInputCellType = CellType('WeaInputCellType');
                        let table;
                        let isAddRow = 1;
                        targetCells.forEach((cell, index) => {
                            if(index===0){
                                table = sheet.tables.find(cell.row, cell.col);
                                if(table) options.oldTableValue = store.dataSourceInstance.getValue(table.bindingPath());
                            }else{
                                if(table&&table.dataRange){
                                    const {row,rowCount,col,colCount} = table.dataRange();
                                    const bindingPath = table.bindingPath();
                                    const rowControl = store.rowControl;
                                    const sheetName = sheet.name();
                                    (rowControl[sheetName]||[]).forEach(item => {
                                        if(bindingPath == item.bindingPath){
                                            isAddRow = item.isAddRow;
                                            return;
                                        }
                                    });
                                    if(1==isAddRow){
                                        if(cell.row>row+rowCount-1){
                                            const tableValue = store.dataSourceInstance.getValue(bindingPath);
                                            const newValue = getNewValue(tableValue,cell.row-row-1,[],1);
                                            store.dataSourceInstance.setValue(bindingPath, newValue);
                                            table.bindingPath(bindingPath);
                                            const rowHeight = sheet.getRowHeight(row+rowCount-1,GC.Spread.Sheets.SheetArea.viewport);
                                            sheet.setRowHeight(cell.row, rowHeight, GC.Spread.Sheets.SheetArea.viewport);
                                            for(var c=0;c<colCount;c++){
                                                const cstyle = sheet.getStyle(row+rowCount-1,cell.col+c,GC.Spread.Sheets.SheetArea.viewport, true);
                                                if(cstyle) {
                                                    cstyle.cellType = null;
                                                    sheet.setStyle(cell.row,cell.col+c,cstyle,GC.Spread.Sheets.SheetArea.viewport);
                                                }
                                            }
                                            store.calcAll(true, sheet.name());
                                        }
                                    }
                                }
                            }
                            const cellObj = sheet.getCell(cell.row,cell.col);
                            if (isEditableArea(cellObj) && cellObj.cellType() && cellObj.cellType().viewAttr != '1') {
                                const value = getValue(index);
                                if (cellObj.cellType() instanceof WeaInputCellType) {
                                    cellObj.text(value);
                                    cellObj.cellType().doUpdateValue(cellObj, value);
                                }
                            }
                        });
                    }
                }
            }
            callback();
        } catch (e) {
            if (!!(window.console && window.console.log)) {
                window.console.log(e);
            }
        }
        context.resumePaint();
    }
};